//
// chat_client.cpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include "tcp_client.h"
#include "stun_message.h"

void tcp_client::write(const chat_message& msg){
    asio::post(io_context_,
               [this, msg]()
               {
                   bool write_in_progress = !write_msgs_.empty();
                   
                   //std::cout << "tcp post: " << write_msgs_.front().data() << write_in_progress << std::endl;

                   write_msgs_.push_back(msg);
                   if (!write_in_progress)
                   {
                       do_write();
                   }
               });
}

void tcp_client::close(){
    asio::post(io_context_, [this]() { socket_.close(); });
}

void tcp_client::do_connect(const tcp::resolver::results_type& endpoints){
    asio::async_connect(socket_, endpoints,
                        [this](std::error_code ec, tcp::endpoint)
                        {
                            if (!ec)
                            {
                                do_read_header();
                            }
                        });
}

void tcp_client::do_read_body(){
    asio::async_read(socket_,
                     asio::buffer(read_msg_.body(), read_msg_.body_length()),
                     [this](std::error_code ec, std::size_t /*length*/)
                     {
                         if (!ec)
                         {
                             if(read_msg_.body_length() >= 10){
                                 std::string message(read_msg_.body(), read_msg_.body_length());
                                 std::cout << "peer info : " << message << std::endl;
                                 peer_.push_back(message);
                             }
                             else{
                                 //std::cout << " read_msg_ len is too short : " <<  read_msg_.body_length() << std::endl;
                             }

                             do_read_header();
                         }
                         else
                         {
                             socket_.close();
                         }
                     });
}

void tcp_client::do_write(){
    asio::async_write(socket_,
                      asio::buffer(write_msgs_.front().data(),
                                   write_msgs_.front().length()),
                      [this](std::error_code ec, std::size_t /*length*/)
                      {
                          //std::cout << "tcp write: " << write_msgs_.front().data() << " ec: " << ec.message() << std::endl;
                          if (!ec)
                          {
                              write_msgs_.pop_front();
                              if (!write_msgs_.empty())
                              {
                                  do_write();
                              }
                          }
                          else
                          {
                              socket_.close();
                          }
                      });
}

void tcp_client::do_read_header()
{
    asio::async_read(socket_,
                     asio::buffer(read_msg_.data(), chat_message::header_length),
                     [this](std::error_code ec, std::size_t /*length*/)
                     {
                         if (!ec && read_msg_.decode_header())
                         {
                             do_read_body();
                         }
                         else
                         {
                             socket_.close();
                         }
                     });
}






//int main(int argc, char* argv[])
//{
//  try
//  {
//    if (argc != 3)
//    {
//      std::cerr << "Usage: chat_client <host> <port>\n";
//      return 1;
//    }
//
//    asio::io_context io_context;
//
//    tcp::resolver resolver(io_context);
//    auto endpoints = resolver.resolve(argv[1], argv[2]);
//    chat_client c(io_context, endpoints);
//
//    std::thread t([&io_context](){ io_context.run(); });
//
//    char line[chat_message::max_body_length + 1];
//    while (std::cin.getline(line, chat_message::max_body_length + 1))
//    {
//      chat_message msg;
//      msg.body_length(std::strlen(line));
//      std::memcpy(msg.body(), line, msg.body_length());
//      msg.encode_header();
//      c.write(msg);
//    }
//
//    c.close();
//    t.join();
//  }
//  catch (std::exception& e)
//  {
//    std::cerr << "Exception: " << e.what() << "\n";
//  }
//
//  return 0;
//}
